1 package edu.jiangxin.apktoolbox.convert.color.colorspace;
2
3 import java.awt.color.ColorSpace;
4 import java.io.Serial;
5
6 public class HslColorSpace extends ColorSpace {
7 @Serial
8 private static final long serialVersionUID = 1L;
9
10 protected HslColorSpace(int type, int numComponents) {
11 super(type, numComponents);
12 }
13
14 public static HslColorSpace getInstance() {
15 return Holder.INSTANCE;
16 }
17
18 @Override
19 public float[] toRGB(float[] colorvalue) {
20 float h = colorvalue[0];
21 float s = colorvalue[1];
22 float l = colorvalue[2];
23
24 float r, g, b;
25
26 if (s == 0f) {
27 r = g = b = l;
28 } else {
29 float q = l < 0.5f ? l * (1 + s) : l + s - l * s;
30 float p = 2 * l - q;
31 r = hueToRgb(p, q, h + 1/3f);
32 g = hueToRgb(p, q, h);
33 b = hueToRgb(p, q, h - 1/3f);
34 }
35
36 return new float[]{r, g, b};
37 }
38
39 @Override
40 public float[] fromRGB(float[] rgbvalue) {
41 float r = rgbvalue[0];
42 float g = rgbvalue[1];
43 float b = rgbvalue[2];
44
45 float max = Math.max(r, Math.max(g, b));
46 float min = Math.min(r, Math.min(g, b));
47
48 float h, s;
49 float l = (max + min) / 2;
50
51 if (max == min) {
52 h = s = 0f;
53 } else {
54 float delta = max - min;
55 s = l > 0.5f ? delta / (2 - max - min) : delta / (max + min);
56 if (max == r) {
57 h = (g - b) / delta + (g < b ? 6f : 0f);
58 } else if (max == g) {
59 h = (b - r) / delta + 2f;
60 } else {
61 h = (r - g) / delta + 4f;
62 }
63 h /= 6f;
64 }
65
66 return new float[]{h, s, l};
67 }
68
69 @Override
70 public float[] toCIEXYZ(float[] colorvalue) {
71 float[] rgb = toRGB(colorvalue);
72 return ColorSpace.getInstance(CS_sRGB).toCIEXYZ(rgb);
73 }
74
75 @Override
76 public float[] fromCIEXYZ(float[] colorvalue) {
77 float[] rgb = ColorSpace.getInstance(CS_sRGB).fromCIEXYZ(colorvalue);
78 return fromRGB(rgb);
79 }
80
81 private float hueToRgb(float p, float q, float t) {
82 if (t < 0f) t += 1f;
83 if (t > 1f) t -= 1f;
84 if (t < 1/6f) return p + (q - p) * 6f * t;
85 if (t < 1/2f) return q;
86 if (t < 2/3f) return p + (q - p) * (2/3f - t) * 6f;
87 return p;
88 }
89
90 private static class Holder {
91 private static final HslColorSpace INSTANCE = new HslColorSpace(TYPE_HLS, 3);
92 }
93 }